package com.atwisdom.star.core.dsl.modelClass.twins.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.UuidTool;
import com.atwisdom.star.common.vo.ModelType;
import com.atwisdom.star.common.vo.PageInfo;
import com.atwisdom.star.core.dao.pojo.modelClass.hier.HierInstance;
import com.atwisdom.star.core.dao.pojo.modelClass.hier.HierInstanceUtils;
import com.atwisdom.star.core.dao.pojo.modelClass.hier.HierModel;
import com.atwisdom.star.core.dao.pojo.modelClass.logic.LogicModel;
import com.atwisdom.star.core.dao.pojo.modelClass.twins.TwinsInstance;
import com.atwisdom.star.core.dao.pojo.modelClass.twins.TwinsInstanceHistory;
import com.atwisdom.star.core.dao.pojo.modelClass.twins.TwinsModel;
import com.atwisdom.star.core.dao.service.modelClass.twins.TwinsInstanceHistoryService;
import com.atwisdom.star.core.dao.service.modelClass.twins.TwinsInstanceService;
import com.atwisdom.star.core.dao.service.modelClass.twins.TwinsModelService;
import com.atwisdom.star.core.dsl.cache.ModelCacheDslService;
import com.atwisdom.star.core.dsl.modelClass.hier.Impl.HierInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.hier.Impl.HierModelDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.twins.TwinsInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.utils.ListHier;
import com.atwisdom.star.core.dsl.modelClass.utils.ListHierContent;
import com.atwisdom.star.core.dsl.modelClass.utils.QueryBuilder;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class TwinsInstanceDslServiceImpl implements TwinsInstanceDslService {

    private TwinsModelService twinsModelService;
    private TwinsInstanceService twinsInstanceService;
    private TwinsInstanceHistoryService twinsInstanceHistoryService;

    private QueryBuilder queryBuilder;

    private ModelCacheDslService modelCacheDslService;

    private HierModelDslServiceImpl hierModelDslService;
    private HierInstanceDslServiceImpl hierInstanceDslService;

    @Autowired
    public void setModelCacheDslService(ModelCacheDslService modelCacheDslService) {
        this.modelCacheDslService = modelCacheDslService;
    }

    @Autowired
    public void setTwinsModelService(TwinsModelService twinsModelService) {
        this.twinsModelService = twinsModelService;
    }

    @Autowired
    public void setTwinsInstanceService(TwinsInstanceService twinsInstanceService) {
        this.twinsInstanceService = twinsInstanceService;
    }

    @Autowired
    public void setTwinsInstanceHistoryService(TwinsInstanceHistoryService twinsInstanceHistoryService) {
        this.twinsInstanceHistoryService = twinsInstanceHistoryService;
    }

    @Autowired
    public void setQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }
    @Autowired
    public void setHierModelDslService(HierModelDslServiceImpl hierModelDslService) {
        this.hierModelDslService = hierModelDslService;
    }
    @Autowired
    public void setHierInstanceDslService(HierInstanceDslServiceImpl hierInstanceDslService) {
        this.hierInstanceDslService = hierInstanceDslService;
    }

    /**
     * 查询全部摘要（通用）
     * @return 返回搞要列表
     */
    @Override
    public List<JSONObject> queryAllInfo() {
        try {
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, null, "className,updateTime");
            List<TwinsInstance> list = twinsInstanceService.list();
            List<JSONObject> jsonObjectList = new ArrayList<>();
            list.forEach(ins-> jsonObjectList.add(ins.getInfoJsonObject()));
            return jsonObjectList;
        }catch (Exception ex){
            throw new BusinessException("999999", "无条件查询所有模型信息！");
        }
    }

    /**
     * 分页查询全部摘要（通用）
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回全部搞要列表
     */
    @Override
    public PageInfo queryAllInfoByPage(int pageNumber, int pageSize, String orderBy) {
        try {
            Page<TwinsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper,true);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询摘要模型信息！",ex);
        }
    }

    /**
     * 查询全部数据（通用）
     *
     * @return 返回结果
     */
    @Override
    public List<JSONObject> queryAll() {
        try {
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildOrderBy(queryWrapper,null,"className,updateTime");
            List<TwinsInstance> list = twinsInstanceService.list();
            list.forEach(l->{
                List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), l.getClassName(), l.getId());
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), l.getClassName());
                l.setHierModels(hierModels);
                l.setHierInstances(hierInstances);
            });
            return this.getTwinsInsJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "无条件查询所有模型信息！");
        }
    }

    /**
     * 分页无条件查询模型信息
     *
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回值
     */
    @Override
    public PageInfo listAllByPage(int pageNumber,int pageSize,String orderBy) {
        try {
            Page<TwinsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper,false);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }

    /**
     * 查询模型
     *
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> query(String condition,String className,String orderBy) {
        try{
            if (StringUtils.isBlank(className)) {
                className = queryBuilder.getClassNameBy(condition);
            }
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForTwins(condition,className);
            orderBy =   this.transformOrderByForTwins(condition,className,orderBy);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            List<TwinsInstance> list = twinsInstanceService.list(queryWrapper);
            list.forEach(l->{
                List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), l.getClassName(), l.getId());
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), l.getClassName());
                l.setHierInstances(hierInstances);
                l.setHierModels(hierModels);
            });
            return this.getTwinsInsJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "查询模型失败！",ex);
        }
    }

    /**
     * 查询模型
     *
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> query(String condition,String className,String orderBy, String hierValueCondition) {
        try{
            if (StringUtils.isBlank(className)) {
                className = queryBuilder.getClassNameBy(condition);
            }
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForTwins(condition,className);
            orderBy =   this.transformOrderByForTwins(condition,className,orderBy);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            List<TwinsInstance> list = twinsInstanceService.list(queryWrapper);
            list.forEach(l->{
                List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), l.getId(), l.getClassName(), hierValueCondition);
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), l.getClassName());
                l.setHierInstances(hierInstances);
                l.setHierModels(hierModels);
            });
            return this.getTwinsInsJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "查询模型失败！",ex);
        }
    }

    /**
     * 查询模型
     *
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> query(String condition,String className,String orderBy, String hierValueCondition, boolean needRootFlag) {
        try{
            if (StringUtils.isBlank(className)) {
                className = queryBuilder.getClassNameBy(condition);
            }
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForTwins(condition,className);
            orderBy =   this.transformOrderByForTwins(condition,className,orderBy);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            List<TwinsInstance> list = twinsInstanceService.list(queryWrapper);
            list.forEach(l->{
                List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), l.getId(), l.getClassName(), hierValueCondition, needRootFlag);
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), l.getClassName());
                l.setHierInstances(hierInstances);
                l.setHierModels(hierModels);
            });
            return this.getTwinsInsJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "查询模型失败！",ex);
        }
    }

    /**
     * 按类名查找实例
     *
     * @param className 类名
     * @return 返回实例表
     */
    public List<TwinsInstance> queryByClassName(String className) {
        LambdaQueryWrapper<TwinsInstance> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TwinsInstance::getClassName,className);
        wrapper.eq(TwinsInstance::getPublished,true);
        List<TwinsInstance> list = this.twinsInstanceService.list(wrapper);
        List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), className);
        list.forEach(l->{
            List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), className, l.getId());
            l.setHierModels(hierModels);
            l.setHierInstances(hierInstances);
        });
        return list;
    }

    /**
     * 根据id获取实例数据
     *
     * @param id 主键id
     * @return 返回实例
     */
    public TwinsInstance queryById(Long id) {
        if (id!=null) {
            return this.twinsInstanceService.getById(id);
        } else {
            return null;
        }
    }

    /**
     * 根据id获取实例数据
     *
     * @param id 主键id
     * @return 返回实例
     */
    @Override
    public JSONObject queryJsonById(Long id) {
        if (id!=null) {
            TwinsInstance instance = this.twinsInstanceService.getById(id);
            if (instance == null) {
                return null;
            }
            TwinsModel twinsModel = this.modelCacheDslService.queryModel(ModelType.Twins.getCode(), instance.getClassName());
            return instance.getInsJsonObject(twinsModel);
        } else {
            return null;
        }
    }


    /**
     * 根据id获取实例数据及关联的hier数据
     *
     * @param id 主键id
     * @return 返回实例
     */
    public TwinsInstance queryInsWithHierById(Long id) {
        if (id!=null) {
            TwinsInstance twinsInstance = this.twinsInstanceService.getById(id);
            if (twinsInstance!=null) {
                List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), twinsInstance.getId(),  twinsInstance.getClassName(), null);
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), twinsInstance.getClassName());
                twinsInstance.setHierInstances(hierInstances);
                twinsInstance.setHierModels(hierModels);
            }
            return twinsInstance;
        } else {
            return null;
        }
    }

    /**
     * 根据id获取实例数据
     *
     * @param ids 主键ids
     * @return 返回实例
     */
    public List<JSONObject> queryByIds(List<Long> ids) {
        LambdaQueryWrapper<TwinsInstance> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(TwinsInstance::getId,ids);
        List<TwinsInstance> twinsInstanceList = twinsInstanceService.list(wrapper);
        twinsInstanceList.forEach(l->{
            List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), l.getId(),  l.getClassName(), null);
            List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), l.getClassName());
            l.setHierInstances(hierInstances);
            l.setHierModels(hierModels);
        });
        return getTwinsInsJsonObjectList(twinsInstanceList);

    }

    /**
     * 更新状态
     * @param id 实例id
     * @param statusCode 状诚编码
     */
    @Override
    public void updateStatus(Long id, String statusCode) {
        TwinsInstance twinsInstance = queryById(id);
        twinsInstance.setSt0(statusCode);
        updateById(twinsInstance);
    }

    /**
     * 查询实例容器hier
     * @param id 参数
     * @return 返回hier
     */
    public JSONObject queryHierById(Long id) {
        try {
            TwinsInstance twinsInstance = this.twinsInstanceService.getById(id);
            List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), twinsInstance.getClassName(), id);
            List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), twinsInstance.getClassName());
            HierInstanceUtils hierInstanceUtils = new HierInstanceUtils(hierInstances, hierModels);
            return hierInstanceUtils.fetchHier();
        } catch (Exception ex) {
            throw new BusinessException("999999", "查询容器信息失败！");
        }
    }

    /**
     * 按条件分页查询实例摘要
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
   public PageInfo queryInfoByPage(int pageNumber,int pageSize, String condition,String className,String orderBy){
       try {
           if (StringUtils.isBlank(className)) {
               className = queryBuilder.getClassNameBy(condition);
           }
           Page<TwinsInstance> pageInfo = new Page<>(pageNumber, pageSize);
           condition = queryBuilder.transformOperator(condition);
           condition = this.transformConditionForTwins(condition,className);
           orderBy =   this.transformOrderByForTwins(condition,className,orderBy);
           QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
           queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
           queryWrapper.eq("published", true);
           queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
           queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
           return getPageInfoResult(pageInfo, queryWrapper,true);
       }catch (Exception ex){
           throw new BusinessException("999999", "分页无条件查询模型信息！");
       }
    }

    /**
     * 按条件分页查询实例
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    public PageInfo queryByPage(int pageNumber,int pageSize, String condition,String className,String orderBy){
        try {
            if (StringUtils.isBlank(className)) {
                className = queryBuilder.getClassNameBy(condition);
            }
            Page<TwinsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForTwins(condition,className);
            orderBy =   this.transformOrderByForTwins(condition,className,orderBy);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper,false);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }


    /**
     * 按条件分页查询实例
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    public PageInfo queryByPage(int pageNumber,int pageSize, String condition,String className,String orderBy, String hierValueCondition){
        try {
            if (StringUtils.isBlank(className)) {
                className = queryBuilder.getClassNameBy(condition);
            }
            Page<TwinsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForTwins(condition,className);
            orderBy =   this.transformOrderByForTwins(condition,className,orderBy);
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            if (StrUtil.isNotBlank(hierValueCondition)) {
                hierValueCondition = hierValueCondition.replace("'$", "insValues->'$");
            }
            return getPageInfoResult(pageInfo, queryWrapper, false, hierValueCondition);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }


    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param jsonObject 参数
     * @return 返回值
     */
    @Override
    public JSONObject updateById(JSONObject jsonObject) {
        try {
            TwinsInstance instance = this.buildUpdateInstance(jsonObject);
            TwinsModel twinsModel = this.modelCacheDslService.queryModel(ModelType.Twins.getCode(), instance.getClassName());
            this.updateById(instance);
            return instance.getInsJsonObject(twinsModel);
        }catch (Exception ex){
            throw new BusinessException("999999", "更新模型实例失败！");
        }
    }


    public void updateFieldNullById(JSONObject jsonObject){
        String className = jsonObject.getString("className");
        Long id = jsonObject.getLong("id");
        LogicModel logicModel = this.modelCacheDslService.queryModel(ModelType.Logic.getCode(), className);
        JSONObject values = jsonObject.getJSONObject("values");
        JSONObject features = logicModel.fetchFeatures();
        UpdateWrapper<TwinsInstance> updateWrapper = new UpdateWrapper<>();
        // 遍历 JSONObject 对象
        for (String key : features.keySet()) {
            String v = values.getString(key);
            if(StringUtils.isBlank(v)){
                updateWrapper.set(key, null);
            }
        }
        updateWrapper.eq("id",id);
        twinsInstanceService.update(updateWrapper);
    }

    public TwinsInstance  buildUpdateInstance(JSONObject jsonObject){
        String id = jsonObject.getString("id");
        if(StringUtils.isBlank(id)){
            throw new BusinessException("999999", "更新id为空操作失败！");
        }

        TwinsInstance sourceInstance = twinsInstanceService.getById(id);
        if(sourceInstance==null){
            throw new BusinessException("999999", "要更新实例不存在，操作失败！");
        }
        JSONObject sourceInstanceJson = getTwinsInsJsonObjectList(Arrays.asList(sourceInstance)).get(0);
        String className = sourceInstanceJson.getString("className");
        String type = sourceInstanceJson.getString("type");
        if (!existModel(type, className)) {
            throw new BusinessException("999999", "模型不存在,创建实例失败！");
        }
        TwinsModel twinsModel = this.modelCacheDslService.queryModel(ModelType.Twins.getCode(), sourceInstance.getClassName());
        return new TwinsInstance(twinsModel,jsonObject,sourceInstanceJson.getJSONObject("values"));
    }


    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * @param twinsInstance 参数
     * @return 返回值
     */
    public TwinsInstance updateById(TwinsInstance twinsInstance){
        try {
            twinsInstanceService.getBaseMapper().updateById(twinsInstance);
            List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), twinsInstance.getClassName());
            List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), twinsInstance.getClassName(), twinsInstance.getId());
            twinsInstance.setHierInstances(hierInstances);
            twinsInstance.setHierModels(hierModels);
            //添加历史
            TwinsInstance newLogicInstance = this.twinsInstanceService.getById(twinsInstance.getId());
            TwinsInstanceHistory twinsInstanceHistory = new TwinsInstanceHistory();
            BeanUtils.copyProperties(newLogicInstance,twinsInstanceHistory);
            twinsInstanceHistory.setId(null);
            this.twinsInstanceHistoryService.save(twinsInstanceHistory);
            return twinsInstance;
        }catch (Exception ex){
            throw new BusinessException("999999", "更新模型实例失败！");
        }
    }

    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param jsonObjectList 参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> updateByIds(List<JSONObject> jsonObjectList) {
        List<JSONObject> resultJsonList = new ArrayList<>();
        jsonObjectList.forEach(j->{
            JSONObject jsonObject = this.updateById(j);
            resultJsonList.add(jsonObject);

        });
        return resultJsonList;
    }

    /**
     * 绑定实体到静态逻辑节点上，如果hier类型是list，需要创建新节点并绑定
     * @param className 静态逻辑类名
     * @param nodeId  要绑定实体所在的节点
     * @param entityId 绑定实体的Id
     * @return 返回结静态逻辑实例json
     */
    public JSONObject bindEntityToHier(String className, String nodeId, Long entityId){
        TwinsModel model = this.modelCacheDslService.queryModel(ModelType.Twins.getCode(), className);
        JSONObject hierProperties = model.getHierProperties();
        TwinsInstance twinsInstance = this.findByClassName(className);
        JSONObject hier = twinsInstance.getHier();
        String type = hier.getString("type");
        JSONArray content = hier.getJSONArray("content");
        if(content==null){
            content = new JSONArray();
        }
        switch (type) {
            case "list":
                ListHier listHier = new ListHier(hierProperties);
                List<ListHierContent> listHierContent = listHier.getContent();
                listHierContent.get(0).getLink().put("id",entityId);
                listHierContent.get(0).setId(UuidTool.getUUID32());
                content.add(listHierContent.get(0));
                this.twinsInstanceService.updateById(twinsInstance);
                return twinsInstance.getInsJsonObject(model);
            case "dictionary":
            case "tree":
            case "chain":
            case "treeChain":
                content.forEach(c->{
                    JSONObject obj = (JSONObject) c;
                    String id = obj.getString("id");
                    if(id.equals(nodeId)){
                        obj.getJSONObject("link").put("id",entityId);
                    }
                });
                this.twinsInstanceService.updateById(twinsInstance);
                return twinsInstance.getInsJsonObject(model);
            default:
                break;

        }

        return twinsInstance.getInsJsonObject(model);
    }

    /**
     * 绑定实体到静态逻辑节点上，如果hier类型是list，需要创建新节点并绑定
     * @param className 静态逻辑类名
     * @param nodeId  要绑定实体所在的节点
     * @param entityId 绑定实体的Id
     * @return 返回结静态逻辑实例json
     */
    public JSONObject unbindEntityToHier(String className, String nodeId, Long entityId){
        TwinsModel model = modelCacheDslService.queryModel(ModelType.Twins.getCode(), className);
        TwinsInstance twinsInstance = this.findByClassName(className);
        JSONObject hier = twinsInstance.getHier();
        String type = hier.getString("type");
        JSONArray content = hier.getJSONArray("content");
        if(content==null){
            content = new JSONArray();
        }
        switch (type) {
            case "list":
                int removeIndex = -1;
                for (int i = 0; i < content.size(); i++) {
                    JSONObject contentJson = content.getJSONObject(i);
                    JSONObject link = contentJson.getJSONObject("link");
                    String id = link.getString("id");
                    if(String.valueOf(entityId).equals(id)){
                        removeIndex = i;
                    }
                }
                if (removeIndex > -1) {
                    content.remove(removeIndex);
                    hier.put("content",content);
                }
                this.twinsInstanceService.updateById(twinsInstance);
                return twinsInstance.getInsJsonObject(model);
            case "dictionary":
            case "tree":
            case "chain":
            case "treeChain":
                content.forEach(c->{
                    JSONObject obj = (JSONObject) c;
                    String id = obj.getString("id");
                    if(id.equals(nodeId)){
                        obj.getJSONObject("link").put("id","");
                    }
                });
                this.twinsInstanceService.updateById(twinsInstance);
                return twinsInstance.getInsJsonObject(model);
            default:
                break;

        }

        return twinsInstance.getInsJsonObject(model);
    }

    /**
     * 按类名查打容器实例
     *
     * @param className 查询参数
     * @return 返回值
     */
    public TwinsInstance findByClassName(String className) {
        LambdaQueryWrapper<TwinsInstance> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(className),TwinsInstance::getClassName, className);
        wrapper.eq(TwinsInstance::getPublished, true);
        List<TwinsInstance> list = twinsInstanceService.list(wrapper);
        if(CollectionUtil.isNotEmpty(list)){
            return list.get(0);
        }else{
            return null;
        }
    }



    /**
     * 按类型和类名更新模型实例（配置阶段）
     * @param jsonObject 类型
     * @return 返回模型记录
     */
    @Override
    public List<JSONObject> updateClassName(JSONObject jsonObject) {
        String type = jsonObject.getString("type");
        String className = jsonObject.getString("className");
        if (StringUtils.isBlank(type) || StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "更新模型实例：type,className都不能为空！");
        }

        if (!this.existModel(type, className)) {
            throw new BusinessException("999999", "模型不存在，更新模型实例失败！");
        }

        try {
            QueryWrapper<TwinsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("className", className);
            queryWrapper.eq("type", type);
            queryWrapper.eq("published", true);
            List<TwinsInstance> instances = this.twinsInstanceService.list(queryWrapper);
            List<JSONObject> resList = new ArrayList<>();
            instances.forEach(ins->{
                jsonObject.put("id",ins.getId());
                JSONObject upJsonObject = this.updateById(jsonObject);
                resList.add(upJsonObject);
            });
            return resList;
        } catch (Exception ex) {
            throw new BusinessException("999999", "更新模型类型和类名", ex);
        }
    }

    /**
     * 获取分页查询
     * @param pageInfo 分页信息
     * @param queryWrapper 查询wrapper
     * @return 返回结果
     */
    private PageInfo getPageInfoResult(Page<TwinsInstance> pageInfo, QueryWrapper<TwinsInstance> queryWrapper,boolean isInfo) {
        Page<TwinsInstance> queryPage = twinsInstanceService.page(pageInfo, queryWrapper);
        List<TwinsInstance> records = queryPage.getRecords();
        List<JSONObject> jsonObjectList;
        if(isInfo){
            jsonObjectList = this.getTwinsInsInfoJsonObjectList(records);
        }else{
            records.forEach(r->{
                List<HierInstance> hierInstances = this.hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), r.getClassName(), r.getId());
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), r.getClassName());
                r.setHierInstances(hierInstances);
                r.setHierModels(hierModels);
            });
            jsonObjectList = this.getTwinsInsJsonObjectList(records);
        }
        Page<JSONObject> queryPageDTO = new Page<>();
        BeanUtils.copyProperties(queryPage, queryPageDTO);
        queryPageDTO.setRecords(jsonObjectList);
        return PageInfo.of(queryPageDTO);
    }
    /**
     * 获取分页查询
     * @param pageInfo 分页信息
     * @param queryWrapper 查询wrapper
     * @return 返回结果
     */
    private PageInfo getPageInfoResult(Page<TwinsInstance> pageInfo, QueryWrapper<TwinsInstance> queryWrapper,boolean isInfo, String hierCondition) {
        Page<TwinsInstance> queryPage = twinsInstanceService.page(pageInfo, queryWrapper);
        List<TwinsInstance> records = queryPage.getRecords();
        List<JSONObject> jsonObjectList;
        if(isInfo){
            jsonObjectList = this.getTwinsInsInfoJsonObjectList(records);
        }else{
            records.forEach(r->{
                List<HierInstance> hierInstances = hierInstanceDslService.queryByContainerId(ModelType.Twins.getCode(), r.getId(), r.getClassName(), hierCondition);
                List<HierModel> hierModels = this.hierModelDslService.queryByClassName(ModelType.Twins.getCode(), r.getClassName());
                r.setHierInstances(hierInstances);
                r.setHierModels(hierModels);
            });
            jsonObjectList = this.getTwinsInsJsonObjectList(records);
        }
        Page<JSONObject> queryPageDTO = new Page<>();
        BeanUtils.copyProperties(queryPage, queryPageDTO);
        queryPageDTO.setRecords(jsonObjectList);
        return PageInfo.of(queryPageDTO);
    }

    /**
     * 检查模型是否存在
     * @param type 类型
     * @param className 类名称
     * @return 返回是否存，true 存在，false 不存在
     */
    private boolean existModel(String type, String className) {
        QueryWrapper<TwinsModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(type), "type", type);
        queryWrapper.eq(StringUtils.isNotBlank(className), "className", className);
        queryWrapper.eq("published", true);
        long count = this.twinsModelService.count(queryWrapper);
        return count > 0;
    }

    /**
     * 将模型实例列表转成JSONObject 列表
     *
     * @param instances 模型实例
     * @return 返回结果
     */
    public List<JSONObject> getTwinsInsInfoJsonObjectList(List<TwinsInstance> instances) {
        List<JSONObject> jsonList = new ArrayList<>();
        instances.forEach(ins -> {
            JSONObject infoJsonObject = ins.getInfoJsonObject();
            jsonList.add(infoJsonObject);

        });
        return jsonList;
    }

    /**
     * 将模型实例列表转成JSONObject 列表
     *
     * @param instances 模型实例
     * @return 返回结果
     */
    public List<JSONObject> getTwinsInsJsonObjectList(List<TwinsInstance> instances) {
        List<TwinsModel> models = this.twinsModelService.list();
        List<JSONObject> jsonList = new ArrayList<>();
        instances.forEach(ins -> {
            TwinsModel twinsModel = models.stream().filter(m -> m.getClassName().equalsIgnoreCase(ins.getClassName())).findFirst().orElse(null);
            JSONObject insJsonObject = ins.getInsJsonObject(twinsModel);
            jsonList.add(insJsonObject);
        });
        return jsonList;
    }

    /**
     * 查询条件字段转换
     *
     * @param condition            参数
     * @param className            参数
     */
    public String transformConditionForTwins(String condition, String className) {
        if (StringUtils.isBlank(condition)) {
            return "";
        }
        if (StringUtils.isBlank(className)) {
            className = queryBuilder.getClassNameBy(condition);
        }
        if (StringUtils.isBlank(className)) {
            return condition;
        }
        if (StringUtils.isNotBlank(className) && StringUtils.isNotBlank(condition)) {
            TwinsModel twinsModel = modelCacheDslService.queryModel(ModelType.Twins.getCode(), className);
            if (twinsModel != null) {
                List<JSONObject> featureProperties = twinsModel.fetchFeatureProperties();
                for (JSONObject item : featureProperties) {
                    String name = item.getString("name");
                    String code = item.getString("code");
                    // condition = condition.replaceAll(name, code);
                    condition = condition.replaceAll("(?<!['%a-z\\d_\\u4e00-\\u9fa5])"+name, code);
                }
                List<JSONObject> featureNoProperties = twinsModel.fetchNonFeaturesProperties();
                for (JSONObject item : featureNoProperties) {
                    String name = item.getString("name");
                    condition = condition.replaceAll("(?<!['%a-z0-9_\\u4e00-\\u9fa5])"+name,
                            java.util.regex.Matcher.quoteReplacement("JSON_EXTRACT(insValues,'$.")+name+
                                    "')");
                }
            }
        }
        return condition;
    }

    /**
     * 查询条件字段转换
     *
     * @param condition 取className 条件
     * @param className 类名
     * @param orderBy   排序参数
     */
    public String transformOrderByForTwins(String condition, String className, String orderBy) {
        if (StringUtils.isBlank(orderBy)) {
            return "";
        }
        if (StringUtils.isBlank(className)) {
            className = queryBuilder.getClassNameBy(condition);
        }

        if (StringUtils.isBlank(className)) {
            return orderBy;
        }
        orderBy = orderBy.replaceAll(" ", "");
        TwinsModel twinsModel = modelCacheDslService.queryModel("twins", className);
        List<JSONObject> featureProperties = twinsModel.fetchFeatureProperties();
        for (JSONObject item : featureProperties) {
            String name = item.getString("name");
            String code = item.getString("code");
            orderBy = orderBy.replaceAll(name, code);
        }
        return orderBy;
    }
}
